package com.jessefyz.module.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jessefyz.common.exception.CustomException;
import com.jessefyz.common.exception.DataNotFoundException;
import com.jessefyz.common.exception.ParamException;
import com.jessefyz.module.shop.constants.AftersaleConstant;
import com.jessefyz.module.shop.constants.OrderConstants;
import com.jessefyz.module.shop.domain.Aftersale;
import com.jessefyz.module.shop.domain.LitemallOrder;
import com.jessefyz.module.shop.domain.vo.AftersaleVo;
import com.jessefyz.module.shop.mapper.AftersaleMapper;
import com.jessefyz.module.shop.service.IAftersaleService;
import com.jessefyz.module.shop.service.ILitemallOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Random;

/**
 * jessefyz
 * ==================================================================
 * CopyRight © 2017-2099 jessefyz工作室
 * 官网地址：http://www.mdsoftware.cn
 * 技术支持：158899639xx
 * ------------------------------------------------------------------
 * 这不是一个自由软件！未经本公司授权您只能在不用于商业目的的前提下
 * 对本程序代码进行修改和使用；不允许对本程序代码以任何目的的再发布。
 * ==================================================================
 *
 * @ClassName Aftersale
 * @Author jessefyz
 * @Date 2021-09-08
 * @Version 1.0.0
 * @Description 售后Service业务层处理
 */
@Service
public class AftersaleServiceImpl extends ServiceImpl<AftersaleMapper, Aftersale> implements IAftersaleService {

    @Autowired
    private ILitemallOrderService orderService;

    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author jessefyz
     * @Date 2021-09-08
     * @Param [lqw]
     * @Return List<AftersaleVo>
     */
    @Override
    public List<AftersaleVo> listVo(QueryWrapper<Aftersale> lqw) {
        return this.baseMapper.listVo(lqw);
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author jessefyz
     * @Date 2021-09-08
     * @Param [id]
     * @Return AftersaleVo
     */
    @Override
    public AftersaleVo getVoById(Long id) {
        return this.baseMapper.getVo(id);
    }

    @Override
    public String generateAftersaleSn(Long memberId) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String now = df.format(LocalDate.now());
        String aftersaleSn = now + getRandomNum(6);
        while (count(new LambdaQueryWrapper<Aftersale>()
                .eq(Aftersale::getUserId,memberId)
                .eq(Aftersale::getAftersaleSn,aftersaleSn)
            ) > 0) {
            aftersaleSn = now + getRandomNum(6);
        }
        return aftersaleSn;
    }
    private String getRandomNum(Integer num) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveAftersale(Aftersale aftersale) {
        LitemallOrder order = Optional.ofNullable(orderService.getOne(new LambdaQueryWrapper<LitemallOrder>()
                        .eq(LitemallOrder::getId,aftersale.getOrderId())
                        .eq(LitemallOrder::getUserId,aftersale.getUserId())
                ,false)).orElseThrow(()-> new DataNotFoundException("订单不存在"));

        // 订单必须完成才能进入售后流程。
        if(!OrderConstants.isConfirmStatus(order) && !OrderConstants.isAutoConfirmStatus(order)){
            throw new CustomException("不能申请售后");
        }
        BigDecimal amount = order.getActualPrice().subtract(order.getFreightPrice());
        if(aftersale.getAmount().compareTo(amount) > 0){
            throw new ParamException("退款金额不正确");
        }
        Short afterStatus = order.getAftersaleStatus();
        if(afterStatus.equals(AftersaleConstant.STATUS_RECEPT) || afterStatus.equals(AftersaleConstant.STATUS_REFUND)){
            throw new CustomException("已申请售后");
        }
        // 如果有旧的售后记录则删除（例如用户已取消，管理员拒绝）
        this.remove(new LambdaQueryWrapper<Aftersale>()
                .eq(Aftersale::getOrderId,order.getId())
                .eq(Aftersale::getUserId,aftersale.getUserId())
        );

        aftersale.setAddTime(new Date());
        aftersale.setStatus(AftersaleConstant.STATUS_REQUEST);
        aftersale.setAftersaleSn(this.generateAftersaleSn(aftersale.getUserId()));
        this.save(aftersale);

        // 订单的aftersale_status和售后记录的status是一致的。
        order.setAftersaleStatus(AftersaleConstant.STATUS_REQUEST);
        order.setUpdateTime(new Date());
        orderService.updateById(order);
        return true;
    }

    /**
     * 取消售后
     * 如果管理员还没有审核，用户可以取消自己的售后申请
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean cancel(Long currentMemberId, Long id) {
        Aftersale aftersale = Optional.ofNullable(this.getOne(new LambdaQueryWrapper<Aftersale>()
                        .eq(Aftersale::getId,id)
                        .eq(Aftersale::getUserId,currentMemberId)
                ,false)).orElseThrow(()->new DataNotFoundException("售后数据不存在"));

        LitemallOrder order = orderService.getById(aftersale.getOrderId());
        // 订单必须完成才能进入售后流程。
        if(!OrderConstants.isConfirmStatus(order) && !OrderConstants.isAutoConfirmStatus(order)){
            throw new CustomException("不支持售后");
        }
        Short afterStatus = order.getAftersaleStatus();
        if(!afterStatus.equals(AftersaleConstant.STATUS_REQUEST)){
            throw new CustomException("不能取消售后");
        }

        aftersale.setStatus(AftersaleConstant.STATUS_CANCEL);
        aftersale.setUpdateTime(new Date());
        this.updateById(aftersale);
        // 订单的aftersale_status和售后记录的status是一致的。
        order.setAftersaleStatus(AftersaleConstant.STATUS_CANCEL);
        order.setUpdateTime(new Date());
        orderService.updateById(order);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByOrderId(Integer userId, Integer orderId) {
        this.remove(new LambdaQueryWrapper<Aftersale>()
            .eq(Aftersale::getOrderId,orderId)
            .eq(Aftersale::getUserId,userId)
        );
    }
}
